package cc.shacocloud.redis.study.lock;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Date;

/**
 * 互斥锁
 */
public interface MutexLock {

    /**
     * @see #tryLock(String, String, Date)
     */
    @NotNull
    default MutexLockMo tryLock(@NotNull String lockName, @NotNull Date leaseTime) {
        return tryLock(lockName, null, leaseTime);
    }

    /**
     * 尝试获取锁
     * <p>
     * 逻辑：
     * 如果锁不存在，则锁定并且设置过期时间，
     * 如果锁已存在，并且锁的凭证一致则刷新过期时间，如果凭证不一致，则返回过期时间
     *
     * @param lockName             锁的名称
     * @param reentrantCertificate 重入锁凭证，如果凭证为空或者不存在则都将视为第一次尝试获取锁
     * @param leaseTime            过期时间，如果为重入则更新过期时间
     * @return 返回获取锁的状态 {@link MutexLockMo}
     */
    @NotNull
    MutexLockMo tryLock(@NotNull String lockName, String reentrantCertificate, @NotNull Date leaseTime);

    /**
     * 尝试释放锁
     * <p>
     * 逻辑：
     * 如果锁已经不存在， 返回null
     * 如果锁存在，并且锁凭证一致，则删除 key，返回null
     * 如果凭证不一致则释放锁失败返回锁的过期时间
     *
     * @param lockName             锁的名称
     * @param reentrantCertificate 可重入状态凭证
     * @return 返回释放锁的状态 {@link MutexLockMo}
     */
    @Nullable
    MutexLockMo tryUnlock(@NotNull String lockName, @NotNull String reentrantCertificate);

}
